<template>
  <el-form
    ref="userFormRef"
    :model="user"
    label-width="auto"
    label-position="right"
    :rules="rules(user)"
    :readonly="true"
  >
    <el-row :gutter="20">
      <el-space>
        <el-form-item label="头像" prop="photo">
          <el-upload
            v-model:file-list="photoFile"
            :class="{ hide: hideUpload_introduce }"
            :http-request="handleUpload"
            :before-upload="beforeAvatarUpload"
            :auto-upload="true"
            :limit="1"
            list-type="picture-card"
          >
            <el-icon><Plus /></el-icon>
            <template #file="{ file }">
              <div>
                <img
                  class="el-upload-list__item-thumbnail"
                  :src="file.url"
                  alt=""
                />
                <span class="el-upload-list__item-actions">
                  <span
                    class="el-upload-list__item-preview"
                    @click="handlePictureCardPreview"
                  >
                    <el-icon><zoom-in /></el-icon>
                  </span>
                  <span class="el-upload-list__item-delete">
                    <el-icon><Download /></el-icon>
                  </span>
                  <span
                    class="el-upload-list__item-delete"
                    @click="photoRemove"
                  >
                    <el-icon><Delete /></el-icon>
                  </span>
                </span>
                <el-image-viewer
                  v-if="showImageViewer"
                  :url-list="[file.url || '']"
                  @close="close"
                />
              </div>
            </template>
          </el-upload>
          <el-input v-show="false" v-model="user.photo" disabled />
        </el-form-item>
        <el-form-item v-if="!$props.isRegister" label="状态">
          <el-switch
            v-model="user.status"
            style="
              --el-switch-on-color: #13ce66;
              --el-switch-off-color: #ff4949;
            "
            inline-prompt
            :active-value="1"
            :inactive-value="0"
            active-text="开启"
            inactive-text="关闭"
          />
        </el-form-item>
      </el-space>
    </el-row>
    <el-row :gutter="20">
      <el-col :span="$props.isRegister ? 12 : 8">
        <el-form-item label="姓名" prop="name">
          <el-input v-model="user.name" clearable />
        </el-form-item>
      </el-col>
      <el-col :span="$props.isRegister ? 12 : 4">
        <el-form-item label="性别">
          <el-switch
            v-model="user.gender"
            inline-prompt
            :active-value="1"
            :inactive-value="0"
            active-text="男"
            inactive-text="女"
          />
        </el-form-item>
      </el-col>
      <el-col v-if="!$props.isRegister" :span="12">
        <el-form-item label="部门">
          <el-select-v2
            v-model="userDepartment"
            :options="departmentOptions"
            placeholder="用户分配部门"
            filterable
            clearable
            @change="departmentSet"
          />
        </el-form-item>
      </el-col>
    </el-row>
    <el-row :gutter="20">
      <el-col :span="12">
        <el-form-item label="出生年月">
          <el-date-picker
            v-model="user.birthday"
            type="date"
            placeholder="Pick a date"
            style="width: 100%"
            format="YYYY-MM-DD"
            value-format="YYYY-MM-DD"
          />
        </el-form-item>
      </el-col>
      <el-col :span="12">
        <el-form-item label="邮箱" prop="email">
          <el-input v-model="user.email" clearable />
        </el-form-item>
      </el-col>
    </el-row>
    <el-row :gutter="20">
      <el-col :span="12">
        <el-form-item label="手机号" prop="mobile">
          <el-input v-model="user.mobile" clearable />
        </el-form-item>
      </el-col>
      <el-col :span="8">
        <el-form-item label="验证码" prop="verificationCode">
          <el-input v-model="user.verificationCode" clearable />
        </el-form-item>
      </el-col>
      <el-col :span="4">
        <el-link
          type="primary"
          :disabled="timer != 0"
          @click.prevent="sendVerificationCode(userFormRef)"
        >
          {{
            timer === 0
              ? "发送验证码"
              : timer === 60
                ? `发送中 ...`
                : `${timer}秒后可再发送`
          }}
        </el-link>
      </el-col>
    </el-row>
    <el-row :gutter="20">
      <el-col :span="12">
        <el-form-item label="账号" prop="account">
          <el-input
            v-model="user.account"
            :prefix-icon="CreditCard"
            clearable
            :disabled="user.base_field?.id != null"
          />
        </el-form-item>
      </el-col>
      <el-col :span="12">
        <el-form-item v-if="!$props.isRegister" label="角色">
          <el-select-v2
            v-model="userRoles"
            :options="roleOptions"
            placeholder="分配用户角色"
            multiple
            filterable
            clearable
            @change="roleSet"
          />
        </el-form-item>
        <el-form-item v-if="$props.isRegister" label="密码" prop="password">
          <el-space direction="vertical" :size="2">
            <el-input
              v-model="user.password"
              type="password"
              placeholder="账户密码"
              show-password
              :prefix-icon="Lock"
            />
            <div class="psw-lvl-progress">
              <el-progress
                v-if="pswLvlPer > 0"
                :text-inside="true"
                :percentage="pswLvlPer"
                :color="pswLvlColors"
                :stroke-width="20"
              >
                <span> {{ pswLvl }} </span>
              </el-progress>
            </div>
          </el-space>
        </el-form-item>
      </el-col>
    </el-row>
    <el-row justify="center" :gutter="20">
      <el-form-item>
        <el-button type="primary" @click="submit(userFormRef)">
          {{ commitLabel }}
        </el-button>
        <el-button @click="editCancel(userFormRef)">
          {{ cancelLabel }}
        </el-button>
      </el-form-item>
    </el-row>
  </el-form>
</template>

<script lang="ts" setup>
import { CreditCard, Lock } from "@element-plus/icons-vue";
import type {
  SelOption,
  Department,
  User,
} from "@/components/elm/ElmUsrEdit";
import type { Role } from "@/components/elm/ElmRoleEdit";
import type { FormInstance, FormRules } from "element-plus";
import { ref, onActivated, watch, onMounted, PropType, toRef } from "vue";
import { useIntervalFn } from "@vueuse/core";
import { ElMessage, UploadUserFile, UploadProps } from "element-plus";
import { phone, verificationCode as vfCode, email } from "@/lib/formCheck";
import { validateUserAccount, validateUserPassword } from "@/lib/inputCheck";
import { UserPostApi, RegisterApi, SendVfCodeApi } from "@/apis/home";
import { level } from "@/lib/passwordCheck";

const dataInfoToOptions = (infos: any[]) => {
  let res: SelOption[] = [];
  if (!infos) return res;
  for (let i in infos) {
    res.push({
      value: infos[i].code,
      label: infos[i].name,
    });
  }
  return res;
};

const props = defineProps({
    user: {
      type: Object as PropType<User>,
      default: () => ({}),
    },
    roles: {
      type: Array as PropType<Role[]>,
      default: () => [],
    },
    departments: {
      type: Array as PropType<Department[]>,
      default: () => [],
    },
    isRegister: {
      type: Boolean,
      default: false,
    },
    commitLabel: {
      type: String,
      default: "提交",
    },
    cancelLabel: {
      type: String,
      default: "取消",
    },
  }),
  emit = defineEmits(["update:user", "cancel", "commit"]),
  userFormRef = ref<FormInstance>(),
  photoFile = ref<UploadUserFile[]>([]),
  hideUpload_introduce = ref(false),
  showImageViewer = ref(false),
  userDepartment = ref<String>(),
  rules = (d: User): FormRules => {
    return {
      photo: [{ required: true, message: "头像不能为空", trigger: "change" }],
      name: [
        { required: true, message: "姓名不能为空", trigger: "blur" },
        { min: 3, max: 5, message: "姓名内容在3到5个字", trigger: "blur" },
      ],
      account: [
        {
          required: true,
          validator: (rule, value, cb) => {
            let id = "0";
            if (d && d.base_field && d.base_field.id) id = d.base_field.id;
            validateUserAccount(rule, id, value, cb);
          },
          trigger: "blur",
        },
        { min: 8, max: 16, message: "账号内容在8到16个字", trigger: "blur" },
      ],
      mobile: phone,
      verificationCode: vfCode,
      email: email,
      password: [
        {
          required: true,
          validator: (rule, value, cb) => {
            validateUserPassword(rule, d.account, value, cb);
          },
          trigger: "blur",
        },
      ],
    };
  },
  user = toRef(props.user),
  departmentOptions = toRef(dataInfoToOptions(props.departments)),
  timer = ref(0),
  userRoles = ref<Array<String>>([]),
  roleOptions = toRef(dataInfoToOptions(props.roles)),
  pswLvlPer = ref(0),
  pswLvlColors = [
    { color: "black", percentage: 20 },
    { color: "red", percentage: 40 },
    { color: "orange", percentage: 60 },
    { color: "green", percentage: 80 },
    { color: "blue", percentage: 100 },
  ],
  pswLvl = ref("");

const { pause, resume } = useIntervalFn(
  () => {
    //每次定时任务 控制时间递减
    if (timer.value <= 0) {
      // 停止递减：停止定时器
      pause();
      localStorage.removeItem("startTimeLogin");
    } else {
      timer.value -= 1;
    }
  },
  1000,
  {
    // 首次是否自动启动定时任务：true（默认值，自动启动），false，不需要自动启动
    immediate: false,
    // 是否延时执行定时任务（false(默认值)，不延时；true表示延时）
    immediateCallback: false,
  }
);

const handleUpload: UploadProps["httpRequest"] = (file: any) => {
    return new Promise(() => {
      console.log("upload");
    });
  },
  getBase64 = (file: any) => {
    return new Promise((resolve, reject) => {
      let reader = new FileReader();
      let fileResult: string | ArrayBuffer | null = "";
      reader.readAsDataURL(file); //开始转
      reader.onload = function () {
        fileResult = reader.result;
      }; //转 失败
      reader.onerror = function (error) {
        reject(error);
      }; //转 结束  咱就 resolve 出去
      reader.onloadend = function () {
        resolve(fileResult);
      };
    });
  },
  beforeAvatarUpload: UploadProps["beforeUpload"] = (file) => {
    const isJPG = file.type === "image/jpeg";
    const isPNG = file.type === "image/png";
    const isLt5M = file.size / 1024 / 1024 < 1;
    if (!isJPG && !isPNG) {
      ElMessage.error("上传图片只能是JPG或者PNG格式!");
    }
    if (!isLt5M) {
      ElMessage.error("上传图片大小不能超过 1MB!");
    }
    if ((isJPG || isPNG) && isLt5M) {
      hideUpload_introduce.value = true;
      getBase64(file).then((res: any) => {
        user.value.photo = res;
      });
      return true;
    }
    photoFile.value = [];
    hideUpload_introduce.value = false;
    return false;
  },
  handlePictureCardPreview = () => {
    showImageViewer.value = true;
  },
  photoRemove = () => {
    photoFile.value = [];
    hideUpload_introduce.value = false;
    user.value.photo = "";
  },
  close = () => {
    showImageViewer.value = false;
  },
  departmentSet = (vals: any) => {
    for (let j in props.departments) {
      if (props.departments[j].code === vals) {
        user.value.department = props.departments[j];
        break;
      }
    }
  },
  sendVerificationCode = async (formEl: FormInstance | undefined) => {
    if (!formEl) return;
    formEl.validateField("mobile", (valid) => {
      if (valid) {
        timer.value = 60;
        SendVfCodeApi(user.value.mobile)
          .then((res: any) => {
            console.log(res.status, res.data.code);
            if (200 == res.status && 200 == res.data.code) {
              //开启定时效果
              // 重启定时器
              resume();
              localStorage.setItem(
                "startTimeLogin",
                String(new Date().getTime())
              );
            } else {
              timer.value = 0;
              ElMessage.error(res.data.msg);
            }
          })
          .catch((err: any) => {
            timer.value = 0;
            ElMessage.error("发送验证码出现错误！");
          });
      }
    });
  },
  roleSet = (vals: any) => {
    let roles = [];
    for (let i in vals) {
      for (let j in props.roles) {
        if (props.roles[j].code === vals[i]) {
          roles.push(props.roles[j]);
        }
      }
    }
    user.value.roles = roles;
  },
  submit = async (formEl: FormInstance | undefined) => {
    if (!formEl) return;
    await formEl.validate((valid, fields) => {
      if (valid) {
        if (!props.isRegister) {
          UserPostApi(user.value)
            .then((res: any) => {
              if (200 == res.status && 200 == res.data.code) {
                ElMessage.success("保存成功！");
                user.value.verificationCode = "";
                user.value.base_field = {
                  id: res.data.data.base_field.id,
                  created_tm: res.data.data.base_field.created_tm,
                  modify_tm: res.data.data.base_field.modify_tm,
                  creator_ac: res.data.data.base_field.creator_ac,
                  creator_nm: res.data.data.base_field.creator_nm,
                  mender_ac: res.data.data.base_field.mender_ac,
                  mender_nm: res.data.data.base_field.mender_nm,
                  version: res.data.data.base_field.version,
                };
                emit("commit");
              } else {
                ElMessage.error(res.data.msg);
              }
            })
            .catch((err) => {
              ElMessage.error("保存出现错误！");
            });
        } else {
          RegisterApi(user.value)
            .then((res) => {
              if (200 == res.status && 200 == res.data.code) {
                ElMessage.success("注册成功！");
                emit("update:user", user.value);
                emit("commit");
                if (formEl) formEl.resetFields();
                user.value.birthday = "";
                photoRemove();
              } else {
                ElMessage.error(res.data.msg);
              }
            })
            .catch((err) => {
              ElMessage.error("注册出现错误！");
            });
        }
      }
    });
  },
  editCancel = (formEl: FormInstance | undefined) => {
    if (formEl) formEl.resetFields();
    user.value.birthday = "";
    photoRemove();
    emit("cancel");
  };

onMounted(() => {
  let startTime = Number(localStorage.getItem("startTimeLogin"));
  let nowTime = new Date().getTime();
  if (startTime) {
    let surplus = 60 - parseInt(String((nowTime - startTime) / 1000), 10);
    timer.value = surplus <= 0 ? 0 : surplus;
    resume();
  }
});

onActivated(() => {
  if (userFormRef.value) userFormRef.value.resetFields();
  user.value.birthday = "";
  photoRemove();
});

watch(
  () => props.user,
  (newValue) => {
    if (userFormRef.value) userFormRef.value.resetFields();
    photoFile.value = [];
    hideUpload_introduce.value = false;
    user.value = toRef(newValue).value;
    userRoles.value = [];
    userDepartment.value = "";
    if (user.value.department) {
      userDepartment.value = user.value.department.code;
    }
    for (
      var i = 0;
      user.value.roles != null && i < user.value.roles.length;
      i++
    ) {
      userRoles.value.push(user.value.roles[i].code);
    }
    if (user.value.photo) {
      photoFile.value.push({
        name: "test",
        url: user.value.photo,
      });
      hideUpload_introduce.value = true;
    }
  }
);

watch(
  () => props.roles,
  (newValue) => {
    roleOptions.value = dataInfoToOptions(newValue);
  }
);

watch(
  () => props.departments,
  (newValue) => {
    departmentOptions.value = dataInfoToOptions(newValue);
  }
);

// 监听注册页面的新密码变化状态，来改变密码强弱显示
watch(
  () => user.value.password,
  (newVal) => {
    if (newVal && newVal != "") {
      const res: string = level(newVal);
      if (res == "非常弱") {
        pswLvlPer.value = 20;
        pswLvl.value = "非常弱";
      } else if (res == "弱") {
        pswLvlPer.value = 40;
        pswLvl.value = "弱";
      } else if (res == "一般") {
        pswLvlPer.value = 60;
        pswLvl.value = "一般";
      } else if (res == "强") {
        pswLvlPer.value = 80;
        pswLvl.value = "强";
      } else if (res == "非常强") {
        pswLvlPer.value = 100;
        pswLvl.value = "非常强";
      }
    } else {
      pswLvlPer.value = 0;
      pswLvl.value = "";
    }
  }
);
</script>

<style scoped>
.hide :deep(.el-upload--picture-card) {
  display: none;
}
.psw-lvl-progress {
  width: 200px;
  min-width: 100px;
  max-width: 600px;
}
</style>
